﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DBMS.Models.DataInterfaces;
using DBMS.Data;
using DBMS.Models;
using DBMS.Models.Query;

namespace DBMS.Controllers
{
    public class ColumnsController : Controller
    {
        private ITableRepository tableRepository;
        private IDatabaseRepository databaseRepository;
        private IColumnRepository columnRepository;
        private IValueRepository valueRepository;
        private IRelationshipRepository relationshipRepository;

        public ColumnsController()
        {
            this.databaseRepository = new DatabaseRepository();
            this.tableRepository = new TableRepository();
            this.columnRepository = new ColumnRepository();
            this.valueRepository = new ValueRepository();
            this.relationshipRepository = new RelationshipRepository();
        }

        public JsonResult GetAllColumnsForTable(string databaseId, string tableId)
        {
            IList<Column> columns = columnRepository.GetAllColumnsForTable(Int32.Parse(databaseId), Int32.Parse(tableId));

            return Json(columns, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Index(string databaseId, string tableId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            IList<Column> columns = columnRepository.GetAllColumnsForTable(database.Index, table.Index);

            ViewBag.Database = database;
            ViewBag.Table = table;
            ViewBag.Columns = columns;

            return PartialView();
        }

        public ActionResult CreateColumn(string databaseId, string tableId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            List<string> types = new List<string>();
            types.Add("String");
            types.Add("Int");
            types.Add("Bool");
            types.Add("DateTime");

            SelectList typeList = new SelectList(types);

            ViewBag.Types = typeList;
            ViewBag.Database = database;
            ViewBag.Table = table;

            return PartialView();
        }

        public ActionResult EditColumn(string databaseId, string tableId, string columnId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            Column column = columnRepository.GetColumn(database.Index, table.Index, Int32.Parse(columnId));

            List<string> types = new List<string>();
            types.Add("String");
            types.Add("Int");
            types.Add("Bool");

            SelectList typeList = new SelectList(types);

            ViewBag.Types = typeList;
            ViewBag.Database = database;
            ViewBag.Table = table;

            return View(column);
        }

        [HttpPost]
        public ActionResult EditColumn(string databaseId, string tableId, Column column)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            columnRepository.UpdateColumn(database.Index, table.Index, column);

            return RedirectToAction("Index", "Columns", new { databaseId = database.Index, tableId = table.Index });
        }

        [HttpPost]
        public ActionResult CreateColumn(string databaseId, string tableId, Column column)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            columnRepository.SaveOrUpdate(database.Index, table.Index, column);

            return RedirectToAction("Index", "Columns", new { databaseId = database.Index, tableId = table.Index });
        }

        public ActionResult SetPrimary(string databaseId, string tableId, string columnId)
        {
            columnRepository.SetPrimary(databaseId, tableId, columnId);

            return RedirectToAction("Index", "Columns", new { databaseId = databaseId, tableId = tableId });
        }

        public ActionResult SetForeign(string databaseId, string tableId, string columnId)
        {

            Column column = columnRepository.GetColumn(Int32.Parse(databaseId), Int32.Parse(tableId), Int32.Parse(columnId));

            Table table = tableRepository.GetTable(Int32.Parse(databaseId), Int32.Parse(tableId));

            IList<Table> tables = tableRepository.GetAllTablesForDatabase(Int32.Parse(databaseId));

            RelationshipViewModel viewModel = new RelationshipViewModel();
            viewModel.Tables = new SelectList(tables, "Index", "Name");
            viewModel.ForeignColumn = column;
            viewModel.ForeignTable = table;

            ViewBag.DatabaseId = databaseId;

            return View(viewModel);
        }

        [HttpPost]
        public ActionResult SetForeign(string PrimaryTable, string PrimaryColumn, string ForeignTable, string ForeignColumn, string databaseId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Relationship relationship = new Relationship();

            relationship.PrimaryTable = tableRepository.GetTable(database.Index, Int32.Parse(PrimaryTable));
            relationship.ForeignTable = tableRepository.GetTable(database.Index, Int32.Parse(ForeignTable));
            relationship.PrimaryTableId = relationship.PrimaryTable.Index;
            relationship.ForeignTableId = relationship.ForeignTable.Index;

            relationship.PrimaryColumn = columnRepository.GetColumn(database.Index, relationship.PrimaryTable.Index, Int32.Parse(PrimaryColumn));
            relationship.ForeignColumn = columnRepository.GetColumn(database.Index, relationship.ForeignTable.Index, Int32.Parse(ForeignColumn));
            relationship.PrimaryColumnId = relationship.PrimaryColumn.Index;
            relationship.ForeignColumnId = relationship.ForeignColumn.Index;

            relationshipRepository.Save(database.Index, relationship);

            return RedirectToAction("Index", "Tables", new { databaseId = databaseId });
        }

        public ActionResult DeleteColumn(string databaseId, string tableId, string columnId)
        {
            columnRepository.DeleteColumn(databaseId, tableId, columnId);

            return RedirectToAction("Index", "Columns", new { databaseId = databaseId, tableId = tableId });
        }

        public ActionResult Menu()
        {
            return PartialView();
        }


    }
}
